home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / book / src / event.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  12KB  |  506 lines

  1. /*
  2.  *  マウス イベント処理ライブラリ
  3.  *
  4.  *  1990.9.11   Make By ken
  5. */
  6.  
  7. #include    <stdio.h>
  8. #include    <stdefs.h>
  9. #include    <stdlib.h>
  10. #include    <math.h>
  11. #include    <egb.h>
  12. #include    <mos.h>
  13. #include    <msdos.cf>
  14. #include    "event.h"
  15. #include    "book.h"
  16. #include    "snd.h"
  17. #include    "mouse.h"
  18.  
  19. static  evt_t   *last_node = NULL ;
  20. static  evt_t   evt_node = { NULL,NULL } ;
  21.  
  22. static  int     time_counter = 0 ;
  23. static  int     interval_limit = 2 ;
  24.  
  25. static  int     enable_cancel = TRUE ;
  26. static  int     enable_ground = FALSE ;
  27. static  EVT     cancel = { NULL,NULL } ;
  28. static  EVT     ground = { NULL,NULL } ;
  29. struct  {
  30.     short int   level ;             /*  イベントレベル  */
  31.     void        (*proc)() ;         /*  処理関数  */
  32. } interval = { -1, (void (*)())0 } ;
  33.  
  34.  
  35.  
  36. /*  ボタン状態の検査  */
  37.  
  38. int     lbtn(int sw)    /*  左ボタンが押されていたら、TRUE  */
  39. {
  40.     return (sw & 1) != 0 ? TRUE:FALSE;
  41. }
  42. int     rbtn(int sw)    /*  右ボタンが押されていたら、TRUE  */
  43. {
  44.     return (sw & 2) != 0 ? TRUE:FALSE;
  45. }
  46.  
  47.  
  48.  
  49. /*  イベントの発生をチェック  */
  50.  
  51. static  int     EVT_chk( REGS evt_t *ep, int x, int y, int sw )
  52. {
  53.     int     on ;
  54.  
  55.     on = ( x >= ep->x1 && x <= ep->x2 &&
  56.            y >= ep->y1 && y <= ep->y2 ) ? TRUE : FALSE ;
  57.  
  58.     switch( ep->now )
  59.     {
  60.       case Ev_OFF_MOS:
  61.       case Ev_MOVE_MOS:
  62.       case Ev_DLSEL_MOS:
  63.       case Ev_SELECT_MOS:
  64.         ep->now = Ev_NON ;
  65.         break ;
  66.  
  67.       case Ev_NON:
  68.         if( on == TRUE )
  69.         {
  70.             ep->now = ( sw != 0 ? Ev_CLIP_MOS:Ev_ON_MOS ) ;
  71.             (*ep->proc)( ep, x, y, sw ) ;
  72.         }
  73.         break ;
  74.  
  75.       case Ev_ON_MOS:
  76.         if( on == TRUE )
  77.         {
  78.             if( sw != 0 )
  79.             {
  80.                 ep->now = Ev_CLIP_MOS ;
  81.                 (*ep->proc)( ep, x, y, sw ) ;
  82.             }
  83.         }
  84.         else
  85.         {
  86.             ep->now = Ev_OFF_MOS ;
  87.             (*ep->proc)( ep, x, y, sw ) ;
  88.         }
  89.         break ;
  90.  
  91.       case Ev_CLIP_MOS:
  92.         if( on == TRUE )
  93.         {
  94.             if( sw == 0 )   /*  ボタンを離した  */
  95.             {
  96.                 ep->now = Ev_SELECT_MOS ;
  97.                 (*ep->proc)( ep, x, y, sw ) ;
  98.             }
  99.         }
  100.         else
  101.         {
  102.             ep->now = ( sw != 0 ? Ev_DOLACK_MOS : Ev_MOVE_MOS ) ;
  103.             (*ep->proc)( ep, x, y, sw ) ;
  104.         }
  105.         break ;
  106.  
  107.       case Ev_DOLACK_MOS:
  108.         if( sw == 0 )       /*  ボタンを離した  */
  109.         {
  110.             ep->now = Ev_DLSEL_MOS ;
  111.             (*ep->proc)( ep, x, y, sw ) ;
  112.         }
  113.         break ;
  114.  
  115.       case Ev_REP_MOS:
  116.         if( on == TRUE )
  117.         {
  118.             if( sw == 0 )   /*  ボタンを離した  */
  119.             {
  120.                 ep->now = Ev_SELECT_MOS ;
  121.                 (*ep->proc)( ep, x, y, sw ) ;
  122.             }
  123.             else
  124.                 (*ep->proc)( ep, x, y, sw ) ;
  125.         }
  126.         else
  127.         {
  128.             ep->now = ( sw == 0 ? Ev_DOLACK_MOS : Ev_MOVE_MOS ) ;
  129.             (*ep->proc)( ep, x, y, sw ) ;
  130.         }
  131.         break ;
  132.     }
  133.  
  134.     return ep->now ;
  135. }
  136. static  EVT     *EVT_chk_evt( EVT *cp, int min, int max )
  137. {
  138.     for( ; cp != NULL ; cp = cp->next )
  139.         if( cp->level >= min && cp->level <= max )
  140.             return cp ;
  141.     return NULL ;
  142. }
  143. static  void    int_counter(void)
  144. {
  145. static  int     a = 0;
  146.  
  147.     if (interval_limit > 0 && ++a >= interval_limit)
  148.         a = 0, time_counter++;
  149. }
  150.  
  151. void    EVT_loop(int min_level, int max_level)
  152. {
  153.         evt_t   *ep;
  154.         EVT     *cp;
  155.         int     x, y;
  156. static  int     sw = 0, l_on = FALSE, r_on = FALSE;
  157. static  int     time = 0;
  158.  
  159.     if( !enable_cancel )
  160.         r_on = rbtn( sw ) ;
  161.     l_on = lbtn( sw ) ;
  162.     mos_rdpos( &sw, &x, &y ) ;
  163.  
  164.     /*  インターバル割り込み  */
  165.     if( !islock( last_node ) &&
  166.         interval.level >= min_level && interval.level <= max_level &&
  167.         time != time_counter )
  168.     {
  169.         time = time_counter ;
  170.         (*interval.proc)() ;
  171.     }
  172.  
  173.     /*  右クリックによるキャンセル機能  */
  174.     if( enable_cancel )
  175.     {
  176.         if( cancel.next != NULL && r_on && rbtn( sw ) == FALSE )
  177.         {
  178.             cp = EVT_chk_evt( cancel.next, min_level, max_level ) ;
  179.             cp->proc() ;
  180.         }
  181.         r_on = rbtn( sw ) ;
  182.         sw &= 1 ;
  183.     }
  184.  
  185.     /*  前回のイベントの継続?  */
  186.     if( last_node != NULL &&
  187.         last_node->level >= min_level && last_node->level <= max_level &&
  188.         EVT_chk( last_node, x, y, sw ) == Ev_REP_MOS && islock( last_node ) )
  189.         return ;
  190.  
  191.     /*  イベント発生の検査  */
  192.     for( ep = evt_node.next ; ep != NULL ; ep = ep->next )
  193.         if( ep->level >= min_level && ep->level <= max_level &&
  194.             EVT_chk( ep, x, y, sw ) != Ev_NON )
  195.         {
  196.             last_node = ep ;
  197.             return ;
  198.         }
  199.     last_node = NULL ;
  200.  
  201.     /*  余白のクリックによるイベント  */
  202.     if( enable_ground )
  203.     {
  204.         if( ground.next != NULL )
  205.         {
  206.             cp = EVT_chk_evt( ground.next, min_level, max_level ) ;
  207.             if( cp != NULL && (
  208.                     ( isright(cp) && r_on && rbtn( sw ) == FALSE ) ||
  209.                     ( isleft( cp) && l_on && lbtn( sw ) == FALSE ) ) )
  210.             {
  211.                 cp->proc() ;
  212.                 r_on = rbtn( sw ) ;
  213.             }
  214.         }
  215.     }
  216.  
  217.     return ;
  218. }
  219.  
  220.  
  221.  
  222. /*  イベントの登録・調査とレベル解除、全解除  */
  223.  
  224. static  evt_t   *EVT_get_new_node( int level )
  225. {                       /*  レベルの高い順にソートされるよう、挿入する  */
  226.     evt_t   *tp, *ep ;
  227.  
  228.     ep = &evt_node ;
  229.     for( tp = ep->next ; tp != NULL ; tp = tp->next )
  230.     {
  231.         if( tp->level < level )
  232.             break ;
  233.         ep = tp ;
  234.     }
  235.  
  236.     if( ( tp = malloc( sizeof( evt_t ) ) ) != NULL )
  237.     {
  238.         tp->next = ep->next ;
  239.         tp->back = ep ;
  240.         ep->next = tp ;
  241.         if( tp->next != NULL )
  242.             (tp->next)->back = tp ;
  243.         return tp ;
  244.     }
  245.     return NULL ;
  246. }
  247. static  void    EVT_free_node( evt_t *ep )
  248. {
  249.     (ep->back)->next = ep->next ;
  250.     if( ep->next != NULL )
  251.         (ep->next)->back = ep->back ;
  252.     free( ep ) ;
  253.     if( ep == last_node )
  254.         last_node = NULL ;
  255. }
  256. static  void    EVT_free_node_evt( EVT *cp )
  257. {
  258.     (cp->back)->next = cp->next ;
  259.     if( cp->next != NULL )
  260.         (cp->next)->back = cp->back ;
  261.     free( cp ) ;
  262. }
  263. static  void    EVT_reset_evt( EVT *cp )
  264. {
  265.     EVT     *np ;
  266.  
  267.     for( ; cp != NULL ; cp = np )
  268.     {
  269.         np = cp->next ;
  270.         EVT_free_node_evt( cp ) ;
  271.     }
  272. }
  273.  
  274. #if 0
  275. void    EVT_print_list( void )
  276. {
  277.     evt_t   *ep ;
  278.  
  279.     ep = evt_node.next ;
  280.     while( ep != NULL )
  281.     {
  282.         printf( "level = %d, num = %d\n", ep->level, ep->no ) ;
  283.         ep = ep->next ;
  284.     }
  285.     printf( "\n\n" ) ;
  286. }
  287. #endif
  288.  
  289. evt_t   *EVT_set_node( int x1, int y1, int xs, int ys,
  290.                            int level, void (*proc)(), mevt_t no, int rep)
  291. {
  292.     evt_t   *ep ;
  293.  
  294.     if( ( ep = EVT_get_new_node( level ) ) != NULL )
  295.     {
  296.         ep->flag = rep ;
  297.         ep->level = level ;
  298.         ep->now = Ev_NON ;
  299.         ep->no = no ;
  300.         ep->x1 = x1 ;
  301.         ep->y1 = y1 ;
  302.         ep->x2 = x1+xs ;
  303.         ep->y2 = y1+ys ;
  304.         ep->proc = proc ;
  305.     }
  306.     return ep ;
  307. }
  308. evt_t   *EVT_get_node( int level, mevt_t no )
  309. {                       /*  指定レベルの指定番号のイベントデータを返す  */
  310. evt_t   *ep;
  311.  
  312.     for (ep = evt_node.next; ep != NULL; ep = ep->next)
  313.         if (ep->level == level && ep->no == no)
  314.             return ep;
  315.     return NULL;
  316. }
  317. void    EVT_level_free( int level )
  318. {
  319.     REGS    evt_t   *ep, *tp ;
  320.  
  321.     for( ep = evt_node.next ; ep != NULL ; ep = tp )
  322.     {
  323.         tp = ep->next ;
  324.         if( ep->level == level )
  325.             EVT_free_node( ep ) ;
  326.     }
  327.  
  328.     EVT_unset_cancel( level ) ;
  329.     EVT_unset_ground( level ) ;
  330. }
  331. void    EVT_reset( void )
  332. {
  333.     evt_t   *ep, *tp ;
  334.  
  335.     EVT_control_cancel( ON ) ;
  336.     EVT_control_ground( OFF ) ;
  337.  
  338.     EVT_unset_interval() ;
  339.  
  340.     for( ep = evt_node.next ; ep != NULL ; ep = tp )
  341.     {
  342.         tp = ep->next ;
  343.         EVT_free_node( ep ) ;
  344.     }
  345.  
  346.     EVT_reset_evt( cancel.next ) ;
  347.     EVT_reset_evt( ground.next ) ;
  348. }
  349. void    BTN_set( int x,int y, int xs,int ys, int wind_col,
  350.                             int lev, void (*proc)(), mevt_t evt, int rep )
  351. {
  352.     dsp_box( x,y, x+xs,y+ys, BOX1_COL,BOX2_COL,wind_col ) ;
  353.     EVT_set_node( x,y, xs,ys, lev,proc,evt, rep ) ;
  354. }
  355.  
  356.  
  357.  
  358.  
  359. /*  キャンセル/余白検出の登録・解除・制御  */
  360.  
  361. static  EVT     *EVT_get_new_node_evt( EVT *root )
  362. {
  363.     EVT     *tp ;
  364.  
  365.     if( ( tp = malloc( sizeof( EVT ) ) ) != NULL )
  366.     {
  367.         tp->next = root->next ;
  368.         tp->back = root ;
  369.         root->next = tp ;
  370.         if( tp->next != NULL )
  371.             (tp->next)->back = tp ;
  372.         return tp ;
  373.     }
  374.     return NULL ;
  375. }
  376. static  void    EVT_level_free_evt( EVT *cp, int level )
  377. {
  378.     REGS    EVT     *np ;
  379.  
  380.     for( ; cp != NULL ; cp = np )
  381.     {
  382.         np = cp->next ;
  383.         if( cp->level == level )
  384.             EVT_free_node_evt( cp ) ;
  385.     }
  386. }
  387.  
  388. int     EVT_control_cancel( int flag )
  389. {
  390.     int     org_mode = enable_cancel ;
  391.     enable_cancel = flag ;
  392.     return org_mode ;
  393. }
  394. int     EVT_control_ground( int flag )
  395. {
  396.     int     org_mode = enable_ground ;
  397.     enable_ground = flag ;
  398.     return org_mode ;
  399. }
  400. void    EVT_set_cancel( int level, void (*proc)() )
  401. {
  402.     EVT     *cp ;
  403.  
  404.     if( ( cp = EVT_get_new_node_evt( &cancel ) ) != NULL )
  405.     {
  406.         cp->level = level ;
  407.         cp->proc = proc ;
  408.     }
  409. }
  410. void    EVT_set_ground( int level, void (*proc)(), int sw )
  411. {
  412.     EVT     *cp ;
  413.  
  414.     if( ( cp = EVT_get_new_node_evt( &ground ) ) != NULL )
  415.     {
  416.         cp->level = level ;
  417.         cp->sw = sw ;
  418.         cp->proc = proc ;
  419.     }
  420. }
  421. void    EVT_unset_cancel( int level )
  422. {
  423.     EVT_level_free_evt( cancel.next, level ) ;
  424. }
  425. void    EVT_unset_ground( int level )
  426. {
  427.     EVT_level_free_evt( ground.next, level ) ;
  428. }
  429.  
  430.  
  431.  
  432. /*  インターバル割り込みの登録と解除  */
  433.  
  434. #ifdef VSYNC
  435. # include "vsync.h"
  436. #endif
  437.  
  438. int     EVT_set_interval(int level, int value, void (*proc)())
  439. {
  440. int     counter, absolute;
  441.  
  442. #ifdef VSYNC
  443.     VSYNC_setEvent((void (*)())int_counter);
  444. #else
  445.     SND_int_timer_a_set((void (*)())int_counter);
  446. #endif
  447.  
  448.     interval.level = level;
  449.     interval.proc = proc;
  450.  
  451.     absolute = abs(value);
  452.     counter = 1000-3000/(absolute+3);
  453.     /* 1000 - 1000/value          1->1  10->900  100->990 */
  454.     /* 1000 - 3000/(value+3)      0->1  10->769  100->970 */
  455.     /* 1000 - 5000/(value+5)      0->1  10->666  100->952 */
  456.  
  457.     if (counter > 1000)
  458.         counter = 1000;
  459. #ifdef VSYNC
  460. #else
  461.     SND_fm_timer_a_set(1, counter);
  462. #endif
  463.     if (absolute < 20)
  464.         interval_limit = 3;
  465.     else if (absolute < 60)
  466.         interval_limit = 2;
  467.     else
  468.         interval_limit = 1;
  469.  
  470. #if 0
  471. static  char    buf[256];
  472. sprintf(buf, "  value %3d/counter %3d   ", absolute, counter);
  473. wrt(buf, 0,0, 15,1, 16);
  474. #endif
  475.  
  476.     return absolute < 100 ? (value / absolute) : (value / 40) ;
  477. }
  478. void    EVT_unset_interval( void )
  479. {
  480.     interval.level = -1;
  481.  
  482. #ifdef VSYNC
  483. #else
  484.     SND_fm_timer_a_set(0, 1);
  485. #endif
  486. }
  487.  
  488.  
  489.  
  490.  
  491. #if 0
  492.  
  493. /*  デバッグ用リスト表示ルーチン  */
  494.  
  495. void    EVT_print( void )
  496. {
  497.     evt_t   *ep ;
  498.  
  499.     for( ep = evt_node.next ; ep != NULL ; ep = ep->next )
  500.         printf( "level %3d/flag %2d/no %3d  (%3d-%3d)-(%3d-%3d)\n",
  501.             ep->level, ep->flag, ep->no, ep->x1,ep->y1, ep->x2,ep->y2 ) ;
  502. }
  503.  
  504. #endif
  505.  
  506.